# coding:UTF-8
import os
import random
import shutil
import signal
import sys
from datetime import datetime

import paho.mqtt.client as mqtt
from iniconfig import IniConfig
from pyrtcm import RTCMReader, RTCMParseError


class CrewtrainingMonitor:

    def __init__(self, tenant_code: str, client_id: str, mqtt_host: str, port: int, clean_session: bool,
                 mqtt_username: str, mqtt_password: str, keepalive: int, topic_list: list[tuple[str, int]],
                 delete_log_path: bool):
        self.tenant_code = tenant_code
        self.client_id = client_id
        self.mqtt_host = mqtt_host
        self.port = port
        self.clean_session = clean_session
        self.mqtt_username = mqtt_username
        self.mqtt_password = mqtt_password
        self.keepalive = keepalive
        self.topic_list = topic_list
        self.delete_log_path = delete_log_path

    def initPath(self):
        if self.delete_log_path:
            folder_path = "log"
            # 检查文件夹是否存在
            if os.path.exists(folder_path) and os.path.isdir(folder_path):
                # 删除文件夹及其所有内容
                shutil.rmtree(folder_path)
                print(f"文件夹 {folder_path} 已删除")
            else:
                print(f"文件夹 {folder_path} 不存在")

    def initMqtt(self):

        def handler(topic: str, payload: bytes):
            splits = topic.split("/")
            payload_str = None
            file_name = None
            file_path = None
            if splits[0] == "srm":
                payload_str = payload.decode()
                if splits[1] == "train":
                    if splits[2] == "stroke":
                        file_name = f"stroke_{splits[4]}.txt"
                        file_path = f"log"
                elif splits[1] == "status":
                    file_name = f"status_{splits[3]}.txt"
                    file_path = f"log"
                elif splits[1] == "hr":
                    file_name = f"hr_{splits[3]}.txt"
                    file_path = f"log"
            elif splits[0] == "device":
                file_name = splits[1] + ".log"
                file_path = f"log"
                try:
                    payload_str = RTCMReader.parse(payload)
                except RTCMParseError:
                    print(f"{topic} 解析失败 {payload}")
                    pass

            if file_name and file_path and payload_str:
                if not os.path.exists(file_path):
                    os.makedirs(file_path, exist_ok=True)
                with open(f"{file_path}/{file_name}", "a", encoding="utf-8") as file:
                    file.write(f"{datetime.now()}: {payload_str}\n")
                    print(f"{datetime.now()} {topic} > 写入文件成功")
            else:
                print(f"{topic} 无法写入文件")

        def on_connect(client, userdata, flags, rc):
            if rc == 0:
                print(f"【{self.mqtt_host} {self.port}】mqtt客户端连接成功")
                # 订阅主题
                client.subscribe(self.topic_list)
            else:
                print(f"【{self.mqtt_host} {self.port}】mqtt客户端连接失败 {rc}")

        def on_message(client, userdata, msg):
            handler(msg.topic, msg.payload)

        def on_subscribe(client, userdata, mid, granted_qos):
            print(f"【{self.mqtt_host} {self.port}】mqtt客户端订阅成功 {mid} {granted_qos}")

        def on_disconnect(client, userdata, rc):
            print(f"【{self.mqtt_host} {self.port}】mqtt客户端断开连接 {rc}")

        mqtt_client = mqtt.Client(client_id=self.client_id, clean_session=self.clean_session)
        mqtt_client.username_pw_set(self.mqtt_username, self.mqtt_password)

        mqtt_client.on_connect = on_connect
        mqtt_client.on_message = on_message
        mqtt_client.on_subscribe = on_subscribe
        mqtt_client.on_disconnect = on_disconnect
        mqtt_client.connect(self.mqtt_host, self.port, self.keepalive)

        def signal_handler(signum, frame):
            print(f"收到信号 SIGINT={signum}，正在关闭 MQTT 客户端...")
            mqtt_client.loop_stop()
            mqtt_client.disconnect()
            sys.exit(0)

        signal.signal(signal.SIGINT, signal_handler)

        # 保持网络循环，等待消息
        mqtt_client.loop_forever()


if __name__ == "__main__":
    ini = IniConfig('config_dev.ini')

    client_id = f"py_crewtraining_{random.randint(1000, 9999)}"
    mqtt_host = ini['mqtt']['host']
    port = int(ini.get('mqtt', 'port'))
    clean_session = bool(ini.get('mqtt', 'clean_session'))
    keepalive = int(ini.get('mqtt', 'keepalive'))
    username = ini.get('mqtt', 'username')
    password = ini.get('mqtt', 'password')

    tenant_code = ini['sys']['tenant_code']
    delete_log_path = ini['settings']['delete_log_path'] == 'true'

    topic_list = [
        (f"device/+/upload", 1),
        (f"srm/train/#", 1),
        (f"srm/status/#", 1),
        (f"srm/hr/#", 1),
    ]

    monitor = CrewtrainingMonitor(tenant_code=tenant_code, client_id=client_id, mqtt_host=mqtt_host, port=port,
                                  clean_session=clean_session, mqtt_username=username, mqtt_password=password,
                                  keepalive=keepalive, topic_list=topic_list,
                                  delete_log_path=delete_log_path)
    monitor.initPath()
    monitor.initMqtt()
